module defl.c.ewl.widget;

import defl.c.ecore.data;
import defl.c.ewl.core;

extern (C):

/**
 * @addtogroup Ewl_Widget Ewl_Widget: The Parent Widget Class Common to All Widgets
 * @brief Defines the Ewl_Widget class and it's accessor/modifier functions.
 *
 * The Ewl_Widget extends the Ewl_Object to provide the basic facilities
 * necessary for widgets to interact with the end user. This includes basic
 * callbacks for input events, window information changes, and drawing to the
 * display.
 *
 * @remarks Inherits from Ewl_Object.
 * @if HAVE_IMAGES
 * @image html Ewl_Widget_inheritance.png
 * @endif
 *
 * @{
 */

/**
 * @def EWL_WIDGET_TYPE
 * The type name for the Ewl_Widget widget
 */
const string EWL_WIDGET_TYPE = "widget";

/**
 * @brief A list of things attached to a widget
 */
struct Ewl_Attach_List
{
        void** list;                /**< The attachment list */
        uint bitfield;
}

/**
 * @brief Contains a key and a value pair
 */
struct Ewl_Pair
{
        char* key;        /**< The key */
        char* value;      /**< The value */
}

/**
 * @brief Contains a list of key value pairs
 */
struct Ewl_Pair_List
{
        Ewl_Pair** list;        /**< The key/value list */
        uint bitfield;
}

/**
 * @brief The callback chain contains the length, mask and information on the list
 */
struct Ewl_Callback_Chain
{
        void** list;            /**< The callback list */
        ubyte mask;     /**< The callback mask */
        ubyte len;      /**< Length of the list */
        ubyte index;    /**< Current list index */
}

/**
 * @brief Contains an RGBA set of colours
 */
struct Ewl_Color_Set
{
        ubyte r,        /**< The red value */
                      g,        /**< The green value */
                      b,        /**< The blue value */
                      a;        /**< The alpha value */
}

/**
 * Function pointer for the Ewl widget drag
 */
void* function() Ewl_Widget_Drag;

/**
 * @brief Inherits from Ewl_Object and extends to provide appearance, parent, and
 * callback capabilities.
 */
struct Ewl_Widget
{
        Ewl_Object object; /**< Inherit the base Object class */
        Ewl_Widget* parent; /**< The parent widget, actually a container */

        Ewl_Callback_Chain callbacks[Ewl_Callback_Type.EWL_CALLBACK_MAX + 1];
                                                /**< Callback chain array */
        Ewl_Attach_List* attach;       /**< List of attachments on the widget */

        void* smart_object; /**< Smart Object for the layer stuff */
        void* fx_clip_box;  /**< Clipping rectangle of widget */

        void* theme_object; /**< Appearance shown on canvas */
        char* theme_path;     /**< Path to the file for loading */
        char* theme_group;    /**< Group in theme to use */
        char* theme_state;    /**< State of the appearance */
        char* appearance;   /**< Key to lookup appearance in theme */
        char* inheritance;  /**< Inheritance of path widget */
        int layer;                /**< the layer relative to the parent */

        Ecore_Hash* theme;          /**< Overriding theme settings */
        Ewl_Pair_List theme_text;   /**< Overriding text in theme */
        uint flags;         /**< the widget flags */
}

Ewl_Widget*      ewl_widget_new();
int              ewl_widget_init(Ewl_Widget* w);
void             ewl_widget_free(Ewl_Widget* w);

void             ewl_widget_name_set(Ewl_Widget* w, char* name);
char*            ewl_widget_name_get(Ewl_Widget* w);
Ewl_Widget*      ewl_widget_name_find(char* name);

void             ewl_widget_reparent(Ewl_Widget* widget);
void             ewl_widget_realize(Ewl_Widget* widget);
void             ewl_widget_unrealize(Ewl_Widget* w);
void             ewl_widget_reveal(Ewl_Widget* w);
void             ewl_widget_obscure(Ewl_Widget* w);
void             ewl_widget_show(Ewl_Widget* widget);
void             ewl_widget_hide(Ewl_Widget* widget);
void             ewl_widget_destroy(Ewl_Widget* widget);
void             ewl_widget_configure(Ewl_Widget* widget);

void             ewl_widget_data_set(Ewl_Widget* w, void* k, void* v);
void            *ewl_widget_data_del(Ewl_Widget* w, void* k);
void            *ewl_widget_data_get(Ewl_Widget* w, void* k);

void             ewl_widget_state_set(Ewl_Widget* w, char* state,
                                                Ewl_State_Type flag);

void             ewl_widget_appearance_set(Ewl_Widget* w, char*appearance);
char*            ewl_widget_appearance_get(Ewl_Widget* w);
char*            ewl_widget_appearance_path_get(Ewl_Widget* w);
int              ewl_widget_appearance_path_size_get(Ewl_Widget* w);
int              ewl_widget_appearance_path_copy(Ewl_Widget* w, char* buf,
                                                int size);
void             ewl_widget_appearance_part_text_set(Ewl_Widget* w, 
                                                     char* part,
                                                     char* text);
char*            ewl_widget_appearance_part_text_get(Ewl_Widget* w, char* part);
void             ewl_widget_appearance_text_set(Ewl_Widget* w, char* text);
char*            ewl_widget_appearance_text_get(Ewl_Widget* w);

void             ewl_widget_inherit(Ewl_Widget* widget, char* type);

uint     ewl_widget_type_is(Ewl_Widget* widget, char* type);
uint     ewl_widget_onscreen_is(Ewl_Widget* widget);

void             ewl_widget_parent_set(Ewl_Widget* w, Ewl_Widget* p);
Ewl_Widget*      ewl_widget_parent_get(Ewl_Widget* w);

void             ewl_widget_enable(Ewl_Widget* w);
void             ewl_widget_disable(Ewl_Widget* w);

void             ewl_widget_print(Ewl_Widget* w);
void             ewl_widget_print_verbose(Ewl_Widget* w);
void             ewl_widget_tree_print(Ewl_Widget* w);

void             ewl_widget_layer_top_set(Ewl_Widget* w, int top);
int              ewl_widget_layer_top_get(Ewl_Widget* w);
void             ewl_widget_layer_priority_set(Ewl_Widget* w, int layer);
int              ewl_widget_layer_priority_get(Ewl_Widget* w);

void             ewl_widget_internal_set(Ewl_Widget* w, uint val);
uint             ewl_widget_internal_is(Ewl_Widget* w);

void             ewl_widget_unmanaged_set(Ewl_Widget* w, uint val);
uint             ewl_widget_unmanaged_is(Ewl_Widget* w);

void             ewl_widget_clipped_set(Ewl_Widget* w, uint val);
uint             ewl_widget_clipped_is(Ewl_Widget* w);

void             ewl_widget_focus_send(Ewl_Widget* w);
Ewl_Widget*      ewl_widget_focused_get();

void             ewl_widget_tab_order_append(Ewl_Widget* w);
void             ewl_widget_tab_order_prepend(Ewl_Widget* w);
void             ewl_widget_tab_order_insert(Ewl_Widget* w, uint idx);
void             ewl_widget_tab_order_insert_before(Ewl_Widget* w, Ewl_Widget* before);
void             ewl_widget_tab_order_insert_after(Ewl_Widget* w, Ewl_Widget* after);
void             ewl_widget_tab_order_remove(Ewl_Widget* w);

void             ewl_widget_focusable_set(Ewl_Widget* w, uint val);
uint             ewl_widget_focusable_get(Ewl_Widget* w);

void             ewl_widget_ignore_focus_change_set(Ewl_Widget* w, uint val);
uint             ewl_widget_ignore_focus_change_get(Ewl_Widget* w);

void             ewl_widget_color_set(Ewl_Widget* w, uint r, uint g,
                                                        uint b, uint a);
void             ewl_widget_color_get(Ewl_Widget* w, uint *r, uint *g,
                                                        uint *b, uint *a);

int              ewl_widget_parent_of(Ewl_Widget* c, Ewl_Widget* w);

void             ewl_widget_flags_add(Ewl_Widget* o, uint flags,
                                      uint mask);
void             ewl_widget_flags_remove(Ewl_Widget* o, uint flags,
                                         uint mask);

/*
 * Internally used callbacks, override at your own risk.
 */
void ewl_widget_cb_show(Ewl_Widget* w, void* ev_data, void* user_data);
void ewl_widget_cb_hide(Ewl_Widget* w, void* ev_data, void* user_data);
void ewl_widget_cb_reveal(Ewl_Widget* w, void* ev_data, void* user_data);
void ewl_widget_cb_obscure(Ewl_Widget* w, void* ev_data, void* user_data);
void ewl_widget_cb_realize(Ewl_Widget* w, void* ev_data, void* user_data);
void ewl_widget_cb_unrealize(Ewl_Widget* w, void* ev_data, void* user_data);
void ewl_widget_cb_configure(Ewl_Widget* w, void* ev_data, void* user_data);
void ewl_widget_cb_reparent(Ewl_Widget* w, void* ev_data, void* user_data);
void ewl_widget_cb_enable(Ewl_Widget* w, void* ev_data, void* user_data);
void ewl_widget_cb_disable(Ewl_Widget* w, void* ev_data, void* user_data);
void ewl_widget_cb_focus_in(Ewl_Widget* w, void* ev_data, void* user_data);
void ewl_widget_cb_focus_out(Ewl_Widget* w, void* ev_data, void* user_data);
void ewl_widget_cb_mouse_in(Ewl_Widget* w, void* ev_data, void* user_data);
void ewl_widget_cb_mouse_out(Ewl_Widget* w, void* ev_data, void* user_data);
void ewl_widget_cb_mouse_down(Ewl_Widget* w, void* ev_data, void* user_data);
void ewl_widget_cb_mouse_up(Ewl_Widget* w, void* ev_data, void* user_data);
void ewl_widget_cb_mouse_move(Ewl_Widget* w, void* ev_data, void* user_data);
